#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include "shmem.h"
#include "msg_queue_peer.h"

// 新的数据类型定义（匹配JSON配置）
#define DATA_TYPE_BOOL 1   // type=1
#define DATA_TYPE_INT 2    // type=2
#define DATA_TYPE_FLOAT 3  // type=3

// 设备类型定义
#define DEV_TYPE_STM32 0
#define DEV_TYPE_MODBUS 1

// 控制消息结构
typedef struct ctl_node {
    long type;
    int key;
    int value;
} control_node_t;

// 共享内存结构定义
typedef union {
    int b_val;     // bool类型存储空间
    int i_val;     // 整形值存储空间
    float f_val;   // 浮点值存储空间
} val_t;

typedef struct std_node {
    int key;
    int type;            // 数据类型 (1=bool, 2=int, 3=float)
    int dev_type;        // 设备类型 (0=STM32, 1=Modbus)
    val_t old_val;
    val_t new_val;
    int ret;
} std_node_t;

#define SHM_TOTAL_DEVICES 8

// 修改后的设备打印函数
void print_device(std_node_t *device) {
    // 设备类型描述
    const char *dev_type_str = (device->dev_type == DEV_TYPE_STM32) ? "STM32" : "Modbus";
    
    // 数据类型描述
    const char *data_type_str;
    switch (device->type) {
        case DATA_TYPE_BOOL: data_type_str = "BOOL"; break;
        case DATA_TYPE_INT: data_type_str = "INT"; break;
        case DATA_TYPE_FLOAT: data_type_str = "FLOAT"; break;
        default: data_type_str = "UNKNOWN"; break;
    }
    
    // 状态描述
    const char *status_str = (device->ret == 0) ? "成功" : "失败";
    
    // 值描述
    char value_str[32] = {0};
    switch (device->type) {
        case DATA_TYPE_BOOL:
            snprintf(value_str, sizeof(value_str), "%d", device->new_val.b_val);
            break;
        case DATA_TYPE_INT:
            snprintf(value_str, sizeof(value_str), "%d", device->new_val.i_val);
            break;
        case DATA_TYPE_FLOAT:
            snprintf(value_str, sizeof(value_str), "%.2f", device->new_val.f_val);
            break;
        default:
            snprintf(value_str, sizeof(value_str), "N/A");
            break;
    }
    
    printf("设备 key=%d, 类型=%s, 设备类型=%s, 状态=%s, 值=%s\n",
           device->key, data_type_str, dev_type_str, status_str, value_str);
}

// 发送控制命令到消息队列
void send_control_command(int key, int value) {
    control_node_t control;
    control.type = 1; // 消息类型
    control.key = key;
    control.value = value;
    
    if (msg_queue_send("control", &control, sizeof(control_node_t), 0) < 0) {
        perror("发送控制命令失败");
    } else {
        printf("已发送控制命令: key=%d, value=%d\n", key, value);
    }
}

// 用户输入处理线程
void *input_handler_thread(void *arg) {
    char input[256];
    
    printf("\n控制命令格式: <key> <value>\n");
    printf("例如: 301 1 (设置key=301的设备值为1)\n");
    printf("输入 'exit' 退出程序\n\n");
    
    while (1) {
        printf("请输入控制命令: ");
        fflush(stdout);
        
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break;
        }
        
        // 移除换行符
        input[strcspn(input, "\n")] = '\0';
        
        // 检查退出命令
        if (strcmp(input, "exit") == 0) {
            printf("退出程序\n");
            exit(0);
        }
        
        // 解析输入
        int key, value;
        if (sscanf(input, "%d %d", &key, &value) == 2) {
            send_control_command(key, value);
        } else {
            printf("无效输入格式，请使用: <key> <value>\n");
        }
    }
    
    return NULL;
}

int main() {
    struct shm_param para;
    size_t shm_size = sizeof(int) + SHM_TOTAL_DEVICES * sizeof(std_node_t);
    
    // 1. 初始化共享内存
    if (shm_init(&para, "shm", shm_size) != 0) {
        printf("共享内存初始化失败\n");
        return 1;
    }
    
    // 2. 获取共享内存地址
    if (shm_getaddr(&para) == NULL) {
        printf("获取共享内存地址失败\n");
        return 1;
    }
    
    // 3. 初始化消息队列
    // if (msg_queue_init("control", sizeof(control_node_t), 10) != 0) {
    //     printf("消息队列初始化失败\n");
    //     return 1;
    // }
    
    printf("开始监控共享内存内容...\n");
    printf("按Ctrl+C退出\n\n");
    
    int *total_devices = (int *)shm_getaddr(&para);
    std_node_t *shm_arr = (std_node_t *)((int *)shm_getaddr(&para) + 1);
    
    // 4. 创建用户输入处理线程
    pthread_t tid;
    if (pthread_create(&tid, NULL, input_handler_thread, NULL) != 0) {
        perror("创建输入线程失败");
        return 1;
    }
    pthread_detach(tid);
    
    // 5. 循环打印共享内存内容
    int count = 0;
    while (1) {
        printf("\n=== 共享内存内容 [%d] ===\n", ++count);
        printf("设备总数: %d\n", *total_devices);
        
        for (int i = 0; i < SHM_TOTAL_DEVICES; i++) {
            printf("设备 %d: ", i);
            print_device(&shm_arr[i]);
        }
        
        sleep(1); // 每秒刷新一次
    }
    
    // 注意：这个程序会一直运行，直到被Ctrl+C中断
    // 所以通常不会执行到这里
    shm_del(&para);
    return 0;
}